home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Complementary Applications 2004 February / SGI IRIX 6.5 Complementary Applications 2004 February.iso / dist / cde.idb / usr / dt / share / examples / dtdnd / buff.c.z / buff.c
Encoding:
C/C++ Source or Header  |  2003-11-18  |  17.0 KB  |  617 lines

  1. /*
  2.  * buff.c
  3.  *
  4.  * Copyright 2000, Silicon Graphics, Inc.
  5.  * ALL RIGHTS RESERVED
  6.  * 
  7.  * UNPUBLISHED -- Rights reserved under the copyright laws of the United
  8.  * States.   Use of a copyright notice is precautionary only and does not
  9.  * imply publication or disclosure.
  10.  *
  11.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
  12.  * Use, duplication or disclosure by the Government is subject to restrictions
  13.  * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
  14.  * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
  15.  * in similar or successor clauses in the FAR, or the DOD or NASA FAR
  16.  * Supplement.  Contractor/manufacturer is Silicon Graphics, Inc.,
  17.  * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
  18.  *
  19.  * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
  20.  * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
  21.  * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
  22.  * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
  23.  * GRAPHICS, INC.
  24.  */
  25. /* $XConsortium: buff.c /main/cde1_maint/1 1995/07/17 16:41:27 drk $ */
  26. /*****************************************************************************
  27.  *****************************************************************************
  28.  **
  29.  **   File:         buff.c
  30.  **
  31.  **   Description:  Buffer transfer functions for the CDE Drag & Drop Demo.
  32.  **
  33.  **  (c) Copyright 1993, 1994 Hewlett-Packard Company
  34.  **  (c) Copyright 1993, 1994 International Business Machines Corp.
  35.  **  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  36.  **  (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
  37.  **      Novell, Inc.
  38.  **
  39.  ****************************************************************************
  40.  ************************************<+>*************************************/
  41.  
  42. #include <time.h>
  43.  
  44. #include <X11/Intrinsic.h>
  45.  
  46. #include <Xm/Xm.h>
  47. #include <Xm/List.h>
  48.  
  49. #include <Dt/Dt.h>
  50. #include <Dt/Dnd.h>
  51.  
  52. #include "icon.h"
  53. #include "file.h"
  54. #include "demo.h"
  55. #include "buff.h"
  56.  
  57. extern Widget    topLevel;
  58.  
  59.  /*************************************************************************
  60.  * 
  61.  *    Data Structures & Private Declarations For Appointment Buffers
  62.  * 
  63.  **************************************************************************/
  64.  
  65. /*
  66.  * Appointment structure used to store appointments internally.
  67.  */
  68.  
  69. typedef struct _Appointment {
  70.         char           *date;
  71.         char           *start;
  72.         char           *end;
  73.         char           *what;
  74. } Appointment;
  75.  
  76. /*
  77.  * List of appointments which always appear to be for the current date.
  78.  */
  79.  
  80. char    today[9];       /* initialized in apptCreateList() */
  81.  
  82. Appointment todaysApptList[] = {
  83. #ifdef TEST_APPT_NAMES
  84.         { today, "", "", "Staff Meeting" },          /* no name */
  85.         { today, " 9:30am", "10:00am", "Will's Party1" }, /* duplicate names */
  86.         { today, " 9:30am", "10:00am", "Will's Party2" },
  87. #else
  88.         { today, " 9:00am", " 9:30am", "Staff Meeting" },
  89.         { today, " 9:30am", "10:00am", "Will's Party" },
  90. #endif
  91.         { today, "10:00am", "10:30am", "Conference Call" },
  92.         { today, "10:30am", "11:30am", "Work on Mail" },
  93.         { today, "11:00am", "11:30pm", "B'fast w/ Robert" },
  94.         { today, " 1:30pm", " 2:30pm", "Design Meeting" },
  95.         { today, " 3:00pm", " 4:00pm", "Communications" },
  96.         { today, " 4:00pm", " 4:30pm", "Pick up Dogs" },
  97.         { today, " 5:00pm", " 6:30pm", "Beer Bust" },
  98.         { today, " 7:00pm", " 9:00pm", "Dinner - Stuart" },
  99.         { NULL, NULL, NULL, NULL }
  100. };
  101.  
  102. /*
  103.  * CDE appointment format used to transfer the appointments via drag & drop.
  104.  */
  105.  
  106. char *apptFormat =
  107. "   ** Calendar Appointment **\n\
  108. \n\
  109.         Date:    %s\n\
  110.         Start:   %s\n\
  111.         End:     %s\n\
  112.         What:    %s\n";
  113.  
  114. /*
  115.  * Private Appointment Buffer Function Declarations
  116.  */
  117.  
  118. static void        apptConvertCallback(Widget, XtPointer, XtPointer);
  119. static int        apptCreateList(XmString**);
  120. static void        apptDestroyList(XmString*,int);
  121. static Appointment*    apptFromListEntry(XmString);
  122. static char*        apptGetLabel(char*);
  123.  
  124.  /*************************************************************************
  125.  * 
  126.  *    Appointment Drag & Drop
  127.  * 
  128.  **************************************************************************/
  129.  
  130. /*
  131.  * apptConvertCallback
  132.  *
  133.  * Fills in buffer structure with calendar appointment string based on which
  134.  * appointments are selected in the scrolled list when the drag is started.
  135.  * ihen no appointments are selected, the appointment under the pointer is
  136.  * used. Supply a label for the calendar appointment based on the contents
  137.  * of the appointment.
  138.  */
  139. static void
  140. apptConvertCallback(
  141.         Widget          dragContext,
  142.         XtPointer       clientData,
  143.         XtPointer       callData)
  144. {
  145.         DtDndConvertCallbackStruct *convertInfo =
  146.                                   (DtDndConvertCallbackStruct *) callData;
  147.         DtDndBuffer     *buffers = convertInfo->dragData->data.buffers;
  148.         Widget          apptList = (Widget)clientData;
  149.         int             selectedPos, ii,
  150.                         selectedItemCount;
  151.         XmStringTable   selectedItems;
  152.         char            apptString[1024];
  153.         String          labelString;
  154.         Appointment     *appt;
  155.  
  156.     if (convertInfo == NULL) {
  157.         return;
  158.     }
  159.  
  160.         /*
  161.          * Verify the validity of the callback reason
  162.          */
  163.  
  164.         if (convertInfo->dragData->protocol != DtDND_BUFFER_TRANSFER ||
  165.         (convertInfo->reason != DtCR_DND_CONVERT_DATA &&
  166.              convertInfo->reason != DtCR_DND_CONVERT_DELETE)) {
  167.                 return;
  168.         }
  169.  
  170.         /*
  171.          * Get selected items from the list
  172.          */
  173.  
  174.         XtVaGetValues(apptList,
  175.                 XmNuserData,            &selectedPos,
  176.                 XmNselectedItemCount,   &selectedItemCount,
  177.                 XmNselectedItems,       &selectedItems,
  178.                 NULL);
  179.  
  180.         for (ii = 0; ii < convertInfo->dragData->numItems; ii++) {
  181.  
  182.                 /*
  183.                  * Get the actual appointment(s)
  184.                  */
  185.  
  186.                 if (selectedItemCount == 0) {
  187.                         appt = &todaysApptList[selectedPos-1+ii];
  188.                 } else {
  189.                         appt = apptFromListEntry(selectedItems[ii]);
  190.                 }
  191.                 sprintf(apptString, apptFormat,
  192.             appt->date, appt->start, appt->end, appt->what);
  193.  
  194.                 /*
  195.                  * Supply the appointment(s) for transfer
  196.                  */
  197.  
  198.                 if (convertInfo->reason == DtCR_DND_CONVERT_DATA) {
  199.  
  200.                         /* Copy the appointment into the buffer for transfer */
  201.  
  202.                         buffers[ii].bp = XtNewString(apptString);
  203.                         buffers[ii].size = strlen(buffers[ii].bp);
  204.  
  205.                         /* Supply the name for the appointment */
  206.  
  207.                         labelString = apptGetLabel(apptString);
  208.             if (labelString == NULL) {
  209.                             buffers[ii].name = (char *)NULL;
  210.             } else {
  211.                             buffers[ii].name = XtNewString(labelString);
  212.                             XtFree(labelString);
  213.             }
  214.  
  215.                 /*
  216.                  * Delete the moved appointment(s)
  217.                  */
  218.  
  219.                 } else if (convertInfo->reason == DtCR_DND_CONVERT_DELETE) {
  220.                         printf("Delete appointment for %s\n", appt->what);
  221.                 }
  222.         }
  223. }
  224.  
  225. /*
  226.  * apptDragFinishCallback
  227.  *
  228.  * Free buffer data/names allocated in apptConvertCallback()
  229.  */
  230. void
  231. apptDragFinishCallback(
  232.         Widget          widget,
  233.         XtPointer       clientData,
  234.         XtPointer       callData)
  235. {
  236.     DtDndDragFinishCallbackStruct *dropFinishInfo =
  237.                 (DtDndDragFinishCallbackStruct *)callData;
  238.     DtDndContext    *dragData = dropFinishInfo->dragData;
  239.     int        ii;
  240.  
  241.     for (ii = 0; ii < dragData->numItems; ii++) {
  242.         XtFree(dragData->data.buffers[ii].bp);
  243.         if (dragData->data.buffers[ii].name != NULL)
  244.             XtFree(dragData->data.buffers[ii].name);
  245.     }
  246. }
  247.  
  248. /*
  249.  * apptTransferCallback
  250.  *
  251.  * Handles the transfer of an appointment to the draw area drop site.
  252.  * Adds the appropriate icon to the list of icons on the draw area.
  253.  */
  254. void
  255. apptTransferCallback(
  256.         Widget          widget,
  257.         XtPointer       clientData,
  258.         XtPointer       callData)
  259. {
  260.         DtDndTransferCallbackStruct *transferInfo =
  261.                                 (DtDndTransferCallbackStruct*) callData;
  262.         DtDndBuffer     *buffers;
  263.     IconInfo    *iconList, *iconPtr;
  264.     char        *name;
  265.     char        *filename;
  266.     int        ii;
  267.  
  268.     if (transferInfo == NULL) {
  269.         return;
  270.     }
  271.  
  272.     /*
  273.      * Verify the validity of the callback reason.
  274.      */
  275.     
  276.     if (transferInfo->dropData->protocol != DtDND_BUFFER_TRANSFER ||
  277.         transferInfo->reason != DtCR_DND_TRANSFER_DATA) {
  278.         return;
  279.     }
  280.  
  281.     /*
  282.      * Use abbreviated method of refering to the data buffers.
  283.      */
  284.  
  285.     if (transferInfo != NULL && transferInfo->dropData != NULL) {
  286.             buffers = transferInfo->dropData->data.buffers;
  287.     } else {
  288.         return;
  289.     }
  290.  
  291.     /*
  292.      * Process each item being transfered.
  293.      */
  294.  
  295.         XtVaGetValues(widget, XmNuserData, &iconList, NULL);
  296.         for (ii = 0; ii < transferInfo->dropData->numItems; ii++) {
  297.  
  298.         /*
  299.          * Check format of buffer
  300.          */
  301.  
  302.         /*
  303.          * Transfer the buffer data. Here there is no actual transfer
  304.          * taking place. Only the icons representing the appointments
  305.          * are created to indicate the transfer.
  306.          */
  307.  
  308.                 name = buffers[ii].name;
  309.         if (name == NULL)
  310.             name = "unnamed";
  311.  
  312.         /* Create file from buffer */
  313.  
  314.         filename = fileStoreBuffer(buffers[ii].name,
  315.             buffers[ii].bp, buffers[ii].size);
  316.         printf("Stored buffer into '%s'\n", filename);
  317.         XtFree(filename);
  318.  
  319.         /* Create icon */
  320.  
  321.                 iconPtr = IconNew();
  322.                 IconInitialize(widget, iconPtr,
  323.             transferInfo->x + ii * 10,
  324.                     transferInfo->y + ii * 10,
  325.                     buffers[ii].bp, buffers[ii].size, name, IconByData);
  326.  
  327.         /* Add to icon list on drop site */
  328.  
  329.                 iconPtr->next = iconList;
  330.         if (iconList != NULL) {
  331.             iconList->prev = iconPtr;
  332.         }
  333.         iconList = iconPtr;
  334.                 XtVaSetValues(widget, XmNuserData, iconList, NULL);
  335.     }
  336. }
  337.  
  338. /*
  339.  * apptDragSetup
  340.  *
  341.  * Prepares the appointment list to source drags of appointments with button 1.
  342.  */
  343. void
  344. apptDragSetup(
  345.         Widget          apptDragSource)
  346. {
  347.         XtAddEventHandler(apptDragSource, Button1MotionMask, False,
  348.                 (XtEventHandler)demoDragMotionHandler,
  349.                 (XtPointer)DtDND_BUFFER_TRANSFER);
  350. }
  351.  
  352. /*
  353.  * apptDropSetup
  354.  *
  355.  * Such a function is not needed since the demoDropSetup in demo.c registers
  356.  * the draw area as a drop site for drops of buffers such as appointments.
  357.  */
  358.  
  359. /*
  360.  * apptDragStart
  361.  *
  362.  * Initiates a drag of an appointment from the appointment list provided
  363.  * the pointer is over an appointment in the list.
  364.  */
  365. void
  366. apptDragStart(
  367.         Widget          widget,
  368.         XEvent          *event)
  369. {
  370.         static XtCallbackRec convertCBRec[] = { {apptConvertCallback, NULL},
  371.                                                 {NULL, NULL} };
  372.         static XtCallbackRec dragFinishCBRec[] = 
  373.                           { {demoDragFinishCallback, NULL},
  374.                             {apptDragFinishCallback, NULL},
  375.                                                 {NULL, NULL} };
  376.         static IconInfo *iconPtr = NULL;
  377.         Widget          dragIcon;
  378.         Display         *display = XtDisplay(widget);
  379.         int             itemCount,
  380.                         selectedPos,
  381.                         selectedItemCount;
  382.         char            apptString[1024];
  383.  
  384.         convertCBRec[0].closure = (XtPointer)widget;
  385.  
  386.     /*
  387.      * Get list of selected items from the scrolled list of appointments
  388.      */
  389.  
  390.         XtVaGetValues(widget,
  391.                 XmNitemCount, &itemCount,
  392.                 XmNselectedItemCount, &selectedItemCount,
  393.                 NULL);
  394.  
  395.     /*
  396.      * Find out which item the pointer was over when the drag began
  397.      */
  398.  
  399.         selectedPos = XmListYToPos(widget, event->xmotion.y);
  400.  
  401.         if (selectedPos == 0 || selectedPos > itemCount) {
  402.                 return;
  403.         }
  404.  
  405.         XtVaSetValues(widget, XmNuserData, selectedPos, NULL);
  406.  
  407.     /*
  408.      * Copy the appointment information into an appointment string
  409.      */
  410.  
  411.         sprintf(apptString, apptFormat,
  412.         todaysApptList[1].date, todaysApptList[1].start,
  413.         todaysApptList[1].end, todaysApptList[1].what);
  414.  
  415.     /*
  416.      * Create drag icon for appointment buffer drag
  417.      */
  418.  
  419.         if (iconPtr == NULL) {
  420.                 iconPtr = IconNew();
  421.                 IconInitialize(widget, iconPtr, 0, 0,
  422.             apptString, strlen(apptString), NULL, IconByData);
  423.         }
  424.  
  425.         if (iconPtr->dragIcon == NULL) {
  426.                 iconPtr->dragIcon = DtDndCreateSourceIcon(widget,
  427.                         iconPtr->bitmap, iconPtr->mask);
  428.         }
  429.         if (selectedItemCount > 1) {
  430.                 dragIcon = NULL;
  431.                 itemCount = selectedItemCount;
  432.         } else {
  433.                 dragIcon = iconPtr->dragIcon;
  434.                 itemCount = 1;
  435.         }
  436.  
  437.     /*
  438.      * Start the drag
  439.      */
  440.  
  441.         if (DtDndVaDragStart(widget, event, DtDND_BUFFER_TRANSFER, itemCount,
  442.                         XmDROP_COPY,
  443.                         convertCBRec, dragFinishCBRec,
  444.                         DtNsourceIcon, dragIcon,
  445.             DtNbufferIsText, True,
  446.                         NULL)
  447.             == NULL) {
  448.  
  449.                 printf("DragStart returned NULL.\n");
  450.         }
  451. }
  452.  
  453.  /*************************************************************************
  454.  *
  455.  *    Appointment Creation, Initialization & Destruction
  456.  *
  457.  *************************************************************************/
  458.  
  459. /*
  460.  * apptCreateDragSource
  461.  *
  462.  * Create a scrolling list filled with appointments.
  463.  */
  464. Widget
  465. apptCreateDragSource(
  466.     Widget        parent)
  467. {
  468.     Widget        apptList;
  469.     XmString    *apptListItems;
  470.     int        apptCount;
  471.  
  472.     apptCount = apptCreateList(&apptListItems);
  473.  
  474.         apptList = XtVaCreateManagedWidget("apptList",
  475.                 xmListWidgetClass, parent,
  476.         /*
  477.          * Uncomment the line specifying the selection policy to
  478.          * enable multiple buffer transfers from the scrolled list
  479.          * of appointments. WARNING: There is a bug in the interaction
  480.          * of the scrolled list and Drag and Drop which causes items
  481.          * in the scrolled list which are selected to appear unselected
  482.          * and vice versa.
  483.          */
  484.                 /* XmNselectionPolicy, XmMULTIPLE_SELECT, */
  485.                 XmNitems, apptListItems,
  486.                 XmNitemCount, apptCount,
  487.                 NULL);
  488.  
  489.     apptDestroyList(apptListItems, apptCount);
  490.         
  491.     return apptList;
  492. }
  493.  
  494. /*
  495.  * apptCreateDropSite
  496.  *
  497.  * Such a function is not needed since the drop site is the draw area which
  498.  * is created in demoCreateDropSite() in demo.c
  499.  */
  500.  
  501. /*
  502.  * apptCreateList
  503.  *
  504.  * Creates a list of XmStrings with appointment data in them.
  505.  */
  506. static int
  507. apptCreateList(
  508.         XmString      **appts)
  509. {
  510.         int             ii, apptCount;
  511.         char            tmpStr[256];
  512.         time_t          now;
  513.         struct tm       *tm;
  514.  
  515.         now = time(&now);
  516.         tm = localtime(&now);
  517.  
  518.         sprintf(today, "%2d/%2d/%2d", tm->tm_mon+1, tm->tm_mday, tm->tm_year);
  519.  
  520.         for (ii = 0; todaysApptList[ii].date; ii++);
  521.  
  522.         apptCount = ii;
  523.  
  524.         *appts = (XmString *) XtMalloc(sizeof(XmString) * apptCount);
  525.  
  526.         for (ii = 0; todaysApptList[ii].date; ii++) {
  527.  
  528.                 sprintf(tmpStr, "%s %s", todaysApptList[ii].start,
  529.                                          todaysApptList[ii].what);
  530.  
  531.                 (*appts)[ii] = XmStringCreate(tmpStr, XmFONTLIST_DEFAULT_TAG);
  532.  
  533.         }
  534.         return apptCount;
  535. }
  536.  
  537. /*
  538.  * apptDestroyList
  539.  *
  540.  * Destroys a list of XmStrings with appointment data in them.
  541.  */
  542. static void
  543. apptDestroyList(
  544.         XmString       *appts,
  545.     int        apptCount)
  546. {
  547.     int        ii;
  548.  
  549.         for (ii = 0; ii < apptCount; ii++) {
  550.                 XmStringFree(appts[ii]);
  551.         }
  552.     XtFree((char *)appts);
  553. }
  554.  
  555.  /*************************************************************************
  556.  *
  557.  *    Appointment Utility Functions
  558.  *
  559.  *************************************************************************/
  560.  
  561. /*
  562.  * apptFromListEntry
  563.  *
  564.  * Returns the full appointment based on the text of the appointment as
  565.  * given in the text entry from the scrolled list of appointments.
  566.  */
  567. static Appointment*
  568. apptFromListEntry(
  569.         XmString        listEntry)
  570. {
  571.         int             ii;
  572.         char            *entryText,
  573.                         *string;
  574.  
  575.         /*
  576.          * Get text string from XmString for use in comparisons
  577.          */
  578.  
  579.         XmStringGetLtoR(listEntry, XmFONTLIST_DEFAULT_TAG, &entryText);
  580.  
  581.         for (ii = 0; todaysApptList[ii].what != NULL; ii++) {
  582.                 string = strstr(entryText, todaysApptList[ii].what);
  583.                 if (string != NULL) {
  584.                         XtFree(entryText);
  585.                         return(&todaysApptList[ii]);
  586.                 }
  587.         }
  588.         XtFree(entryText);
  589.         return NULL;
  590. }
  591.  
  592. /*
  593.  * apptGetLabel
  594.  *
  595.  * Creates a label for an appointment icon given an appointment.
  596.  */
  597. static char*
  598. apptGetLabel(
  599.         char            *appt)
  600. {
  601.         char            start[128];
  602.         int             count;
  603.  
  604.         if (appt == NULL) {
  605.                 return NULL;
  606.         }
  607.         appt = strstr(appt, "Start:");
  608.         count = sscanf(appt, "Start:%*[ \t]%[^\n]", start);
  609.  
  610.         if (count != 1) {
  611.                 return NULL;
  612.         }
  613.  
  614.         return XtNewString(start);
  615. }
  616.  
  617.